package com.sanbuTech.util;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Date;
import java.util.Set;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.fastjson.JSONObject;

/**
 * 类描述：json对象和普通类对象的转化
 * 创建人：hyc   
 * 创建时间：2016年1月16日 下午4:00:47
 */
public class JSON2ObjectUtil {

	private static Logger logger = LoggerFactory.getLogger(JSON2ObjectUtil.class);
	
	@SuppressWarnings("unchecked")
	public static <T> T json2Object(JSONObject jsonObj, Class<?> clazz){
		
		if(jsonObj.isEmpty()){
			return null;
		}
		
		Object object;
		try {
			object = clazz.newInstance();
		} catch (InstantiationException | IllegalAccessException e1) {
			// TODO Auto-generated catch block
			logger.error(e1.getMessage(), e1);
			return null;
		}
		
		Method[] methods = clazz.getMethods();
		
		Set<String> keySets= jsonObj.keySet();
		keySets.forEach(key ->{
			//转成驼峰风格
			String field = StringNameStypeUtil.underline2Hump(key);
			//首字母大写
			String setMethodName = new StringBuilder("set").append(field.substring(0, 1).toUpperCase()).append(field.substring(1)).toString();
			try {
				invokeMethod(jsonObj, object, methods, setMethodName, key);
			} catch (IllegalAccessException | IllegalArgumentException
					| InvocationTargetException e) {
				// TODO Auto-generated catch block
				logger.error(e.getMessage(), e);
			}
		});
		
		return (T)object;
	}
	
	/**
	 * 通过反射调用setter方法把参数传进去
	 * @param jsonObj
	 * @param object
	 * @param methods
	 * @param methodName
	 * @param key
	 * @return
	 * @throws IllegalAccessException
	 * @throws IllegalArgumentException
	 * @throws InvocationTargetException
	 */
	private static Object invokeMethod(JSONObject jsonObj, Object object, Method[] methods, String methodName, String key)
			throws IllegalAccessException, IllegalArgumentException,
			InvocationTargetException {
		for(Method method : methods){
			if(method.getName().equals(methodName)){
				Class<?> paramClass = method.getParameters()[0].getType();
				Object param = null;
				//Date参数
				if (paramClass == Date.class) {
					param = jsonObj.getDate(key);
				} else if (paramClass == int.class) {
					param = jsonObj.getIntValue(key);
				} else if (paramClass == long.class) {
					param = jsonObj.getLongValue(key);
				} else if (paramClass == String.class) {
					param = jsonObj.getString(key);
				}
				method.invoke(object, param);
				break;
			}
		}
		return object;
	}
	
}
